/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.util;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.annotation.AnNullable;
import org.zhiqim.kernel.constants.TypeConstants;
import org.zhiqim.kernel.model.lists.ConcurrentSet;
import org.zhiqim.kernel.model.maps.HashMapSO;
import org.zhiqim.kernel.model.maps.HashMapSS;
import org.zhiqim.kernel.model.maps.HashMapSV;
import org.zhiqim.kernel.model.maps.LinkedMapSO;
import org.zhiqim.kernel.model.maps.LinkedMapSS;
import org.zhiqim.kernel.model.maps.LinkedMapSV;
import org.zhiqim.kernel.model.maps.MapSO;
import org.zhiqim.kernel.model.maps.MapSS;
import org.zhiqim.kernel.model.maps.MapSV;
import org.zhiqim.kernel.model.maps.TreeMapSO;
import org.zhiqim.kernel.model.maps.TreeMapSS;
import org.zhiqim.kernel.model.maps.TreeMapSV;
import org.zhiqim.kernel.model.results.RE;

/**
 * 类相关工具类 
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
@AnAlias("Classes")
public class Classes implements TypeConstants
{
    /*************************************************************/
    //新建对象
    /*************************************************************/
    /**
     * 通过类名获取类结构
     * 
     * @param className 类名
     * @return Class<?> 类结构
     */
    public static RE<Class<?>> name(String className)
    {
        try
        {//先在当前ClassLoader尝试,以保证不是系统默认的父ClassLoader优先
            Class<?> value = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
            return RE.value(value);
        }
        catch(Exception e)
        {//ClassNotFoundException时再全局查一次
            try{return RE.value(Class.forName(className));}
            catch (Throwable e1){return RE.error(e1);}
        }
        catch (Throwable e) 
        {//NoClassDefFoundError时直接返回null，一般是引用了其他jar的类，但jar未导入
            return RE.error(e);
        }
    }
    
    /**
     * 通过类名获取类结构
     * 
     * @param className 类名
     * @return Class<?> 类结构
     */
    public static Class<?> forName(String className)
    {
        try
        {//先在当前ClassLoader尝试,以保证不是系统默认的父ClassLoader优先
            return Class.forName(className, true, Thread.currentThread().getContextClassLoader());
        }
        catch(Exception e)
        {//ClassNotFoundException时再全局查一次
            try{return Class.forName(className);}
            catch (Throwable e1){return null;}
        }
        catch (Throwable e) 
        {//NoClassDefFoundError时直接返回null，一般是引用了其他jar的类，但jar未导入
            return null;
        }
    }
    
    /**
     * 初始化实例，忽略异常，异常时返回null
     * @param className 类名
     * @return          实例
     */
    public static Object newInstance(String className)
    {
        try
        {
            Class<?> cls = forName(className);
            return (cls == null)?null:cls.getDeclaredConstructor().newInstance();
        }
        catch (Throwable e)
        {
            return null;
        }
    }
    
    /**
     * 初始化实例，忽略异常，异常时返回null
     * 
     * @param cls       类结构
     * @return          实例
     */
    public static <T> T newInstance(Class<T> cls)
    {
        try{return cls.getDeclaredConstructor().newInstance();}catch (Exception e){return null;}
    }
    
    /**
     * 初始化数组，先创建数组对象，再转化为对象数组，基本类型转为对象类型，如int[]转为Integer[]
     * 
     * @param cls       类结构
     * @param length    数组长度
     * @return          对象数组
     */
    public static Object[] newInstance(Class<?> cls, int length)
    {
        Object obj = Array.newInstance(cls, length);
        return Arrays.toArray(obj);
    }
    
    /**
     * 通过类结构分析集合，得到一个集合对象，当前仅支持
     * 1.Collection.class,List.class,ArrayList.class返回ArrayList对象
     * 2.LinkedList.class返回LinkedList对象
     * 3.Set.class,HashSet.class返回HashSet对象
     * 
     * @param cls   类结构
     * @return      集合对象
     */
    public static Collection<Object> newCollection(Class<?> cls)
    {
        Collection<Object> list = null;
        if (cls == Collection.class || cls == List.class || cls == ArrayList.class)
            return new ArrayList<Object>();
        else if (cls == LinkedList.class)
            return new LinkedList<Object>();
        else if (cls == Set.class || cls == HashSet.class)
            return new HashSet<Object>();
        else if (cls == ConcurrentSet.class)
            return new ConcurrentSet<>();
        else//其他不支持，直接返回null;
            return list;
    }
    
    /**
     * 通过类结构分析集合，得到一个集合对象，当前仅支持
     * 1.List.class,ArrayList.class返回ArrayList对象
     * 2.LinkedList.class返回LinkedList对象
     * 
     * @param cls   类结构
     * @return      列表对象
     */
    public static <T> List<T> newList(Class<?> cls, Class<?> genericsClass)
    {
        List<T> list = null;
        if (cls == List.class || cls == ArrayList.class)
            return new ArrayList<T>();
        else if (cls == LinkedList.class)
            return new LinkedList<T>();
        else//其他不支持，直接返回null;
            return list;
    }
    
    /**
     * 通过类结构分析MAP，得到一个MAP对象，当前仅支持
     * 1.Map.class,HashMap.class，返回HashMap对象
     * 2.ConcurrentMap.class,ConcurrentHashMap.class，返回ConcurrentHashMap对象
     * 3.Hashtable.class返回Hashtable对象
     * 4.LinkedHashMap.class，返回LinkedHashMap对象
     * 5.TreeMap.class，返回TreeMap对象
     * 
     * @param cls   类结构
     * @return      MAP对象
     */
    public static Map<String, Object> newMap(Class<?> cls)
    {
        Map<String, Object> map = null;
        if (cls == Map.class || cls == HashMap.class)
            return new HashMap<String, Object>();
        else if (cls == ConcurrentMap.class || cls == ConcurrentHashMap.class)
            return new ConcurrentHashMap<String, Object>();
        else if (cls == Hashtable.class)
            return new Hashtable<String, Object>();
        else if (cls == LinkedHashMap.class)
            return new LinkedHashMap<String, Object>();
        else if (cls == TreeMap.class)
            return new TreeMap<String, Object>();
        else//不支持的类型
            return map;
    }
    
    /**
     * 通过类结构分析MAP，得到一个MAP对象，当前仅支持
     * 1.MapSO.class,HashMapSO.class，返回HashMap对象
     * 2.LinkedMapSO.class，返回LinkedMapSO对象
     * 3.TreeMapSO.class，返回TreeMapSO对象
     * 
     * @param cls   类结构
     * @return      MAP对象
     */
    public static MapSO newMapSO(Class<?> cls)
    {
        MapSO map = null;
        if (cls == MapSO.class || cls == HashMapSO.class)
            return new HashMapSO();
        else if (cls == LinkedMapSO.class)
            return new LinkedMapSO();
        else if (cls == TreeMapSO.class)
            return new TreeMapSO();
        else//不支持的类型
            return map;
    }
    
    /**
     * 通过类结构分析MAP，得到一个MAP对象，当前仅支持
     * 1.MapSS.class,HashMapSS.class，返回HashMap对象
     * 2.LinkedMapSS.class，返回LinkedMapSS对象
     * 3.TreeMapSS.class，返回TreeMapSS对象
     * 
     * @param cls   类结构
     * @return      MAP对象
     */
    public static MapSS newMapSS(Class<?> cls)
    {
        if (cls == MapSS.class || cls == HashMapSS.class)
            return new HashMapSS();
        else if (cls == LinkedMapSS.class)
            return new LinkedMapSS();
        else if (cls == TreeMapSS.class)
            return new TreeMapSS();
        else//不支持的类型
            return null;
    }
    
    /**
     * 通过类结构分析MAP，得到一个MAP对象，当前仅支持
     * 1.MapSS.class,HashMapSS.class，返回HashMap对象
     * 2.LinkedMapSS.class，返回LinkedMapSS对象
     * 3.TreeMapSS.class，返回TreeMapSS对象
     * 
     * @param cls   类结构
     * @return      MAP对象
     */
    public static <V> MapSV<V> newMapSV(Class<?> cls, Class<V> gcls)
    {
        if (cls == MapSS.class || cls == HashMapSS.class)
            return new HashMapSV<V>();
        else if (cls == LinkedMapSS.class)
            return new LinkedMapSV<V>();
        else if (cls == TreeMapSS.class)
            return new TreeMapSV<V>();
        else//不支持的类型
            return null;
    }
    
    /**
     * 通过类结构和参数表组装成实例
     * 
     * @param cls                       类结构
     * @param paramMap                  参数表
     * @return                          组装成对象
     * @throws IllegalAccessException   非法访问异常
     */
    public static <T> T newInstance(Class<T> cls, MapSS paramMap) throws IllegalAccessException
    {
        return newInstance(cls, paramMap.instance());
    }
    
    /**
     * 通过类结构和参数表组装成实例
     * 
     * @param cls                       类结构
     * @param paramMap                  参数表
     * @return                          组装成对象
     * @throws IllegalAccessException   非法访问异常
     */
    public static <T> T newInstance(Class<T> cls, Map<String, String> paramMap) throws IllegalAccessException
    {
        T obj = null;
        try{obj = cls.getDeclaredConstructor().newInstance();}catch(Exception e){throw Asserts.exception("类["+cls+"]不支持无参数实例化");}
        
        List<Field> fields = Classes.getFieldListDeep(cls);
        for (Field field : fields)
        {
            String value = paramMap.get(field.getName());
            if (value == null)
            {//前端没有参数的过滤
                continue;
            }
            
            Class<?> type = field.getType();
            if (!Types.isPrimitive(type) && !Types.isPrimitiveArray(type) && type != String.class && type != String[].class)
            {//不支持的属性先过滤，仅支持8个基本类型和基本类型数组、字符串、字符串数组
                continue;
            }
            
            field.setAccessible(true);
            switch (type.getName().hashCode())
            {
            case BOOLEAN_CODE:
            case BOOLEAN_OBJ_CODE:
            {//布尔型
                if ("true".equalsIgnoreCase(value) || "1".equalsIgnoreCase(value))
                    field.setBoolean(obj, true);
                else
                    field.setBoolean(obj, false);
                break;
            }
            case BYTE_CODE:
            case BYTE_OBJ_CODE:
            {//字节型，支持去除0前缀
                if (Validates.isInteger(value) || Validates.isNumeric(value))
                    field.setByte(obj, Byte.parseByte(value));
                break;
            }
            case CHAR_CODE:
            case CHAR_OBJ_CODE:
            {//字符型
                if (value.length() == 1)
                    field.setChar(obj, value.charAt(0));
                break;
            }
            case SHORT_CODE:
            case SHORT_OBJ_CODE:
            {//短整型，支持去除0前缀
                if (Validates.isInteger(value) || Validates.isNumeric(value))
                    field.setShort(obj, Short.parseShort(value));
                break;
            }
            case INT_CODE:
            case INT_OBJ_CODE:
            {//整型，支持去除0前缀
                if (Validates.isInteger(value) || Validates.isNumeric(value))
                    field.setInt(obj, Integer.parseInt(value));
                break;
            }
            case LONG_CODE:
            case LONG_OBJ_CODE:
            {//长整型，支持去除0前缀
                if (Validates.isInteger(value) || Validates.isNumeric(value))
                    field.setLong(obj, Long.parseLong(value));
                break;
            }
            case FLOAT_CODE:
            case FLOAT_OBJ_CODE:
            {//浮点型
                if (Validates.isFloat(value))
                    field.setFloat(obj, Float.parseFloat(value));
                break;
            }
            case DOUBLE_CODE:
            case DOUBLE_OBJ_CODE:
            {//双字节浮点型
                if (Validates.isFloat(value))
                    field.setDouble(obj, Double.parseDouble(value));
                break;
            }
            case STRING_CODE:
            {//字符串
                field.set(obj, value);
                break;
            }
            //以下为数组
            case BOOLEAN_ARR_CODE:
            {//布尔型数组
                boolean[] values = Arrays.toBooleanArrayForm(value, ",");
                field.set(obj, values);
                break;
            }
            case BYTE_ARR_CODE:
            {//字节型数组，指定是UTF-8格式
                if (value.length() > 0)
                    field.set(obj, Strings.getBytesUTF8(value));
                break;
            }
            case CHAR_ARR_CODE:
            {//字符型数组
                if (value.length() > 0)
                    field.set(obj, value.toCharArray());
                break;
            }
            case SHORT_ARR_CODE:
            {//短整型数组
                if (Validates.isInteger(value))
                    field.set(obj, Arrays.toShortArray(value));
                break;
            }
            case INT_ARR_CODE:
            {//整型数组
                if (Validates.isInteger(value))
                    field.set(obj, Arrays.toIntArray(value));
                break;
            }
            case LONG_ARR_CODE:
            {//长整型数组
                if (Validates.isInteger(value))
                    field.set(obj, Arrays.toLongArray(value));
                break;
            }
            case FLOAT_ARR_CODE:
            {//浮点型数组
                if (Validates.isFloat(value))
                    field.set(obj, Arrays.toFloatArray(value));
                break;
            }
            case DOUBLE_ARR_CODE:
            {//双字节浮点型数组
                if (Validates.isFloat(value))
                    field.set(obj, Arrays.toDoubleArray(value));
                break;
            }
            case STRING_ARR_CODE:
            {//字符串数组
                field.set(obj, Arrays.toStringArray(value));
                break;
            }
            }
        }
        
        return obj;
    }
    
    /*************************************************************/
    //判断类结构相关
    /*************************************************************/
    
    /**
     * 判断类结构，是否继承自指定的类（含本类）
     * 
     * @param cls           类结构
     * @param superClass    父类
     * @return              =true表示继承现,=false表示未继承
     */
    public static boolean isExtends(Class<?> cls, Class<?> superClass)
    {
        Asserts.notNull(superClass, "superClass");
        return superClass.isAssignableFrom(cls);
    }
    
    /**
     * 判断类结构，是否实现指定的接口（含本类）
     * 
     * @param cls       类结构
     * @param iface     接口
     * @return          =true表示实现,=false表示未实现
     */
    public static boolean isImplement(Class<?> cls, Class<?> iface)
    {
        Asserts.notNull(iface, "iface");
        return iface.isAssignableFrom(cls);
    }
    
    /**
     * 判断一个类是否是集合类
     * 
     * @param cls       类结构
     * @return          =true表示真
     */
    public static boolean isCollection(Class<?> cls)
    {
        return Collection.class.isAssignableFrom(cls);
    }
    
    /**
     * 判断一个类是否是列表类
     * 
     * @param cls       类结构
     * @return          =true表示真
     */
    public static boolean isList(Class<?> cls)
    {
        return List.class.isAssignableFrom(cls);
    }
    
    /**
     * 判断一个类是否是映射表类
     * 
     * @param cls       类结构
     * @return          =true表示真
     */
    public static boolean isMap(Class<?> cls)
    {
        return Map.class.isAssignableFrom(cls);
    }
    
    /**
     * 判断一个类是否是扩展的MapSV的子类，如HashMapSV
     * 
     * @param cls       类结构
     * @return          =true表示真
     */
    public static boolean isMapSV(Class<?> cls)
    {
        return MapSV.class.isAssignableFrom(cls);
    }
    
    /**
     * 判断是否是静态方法
     * 
     * @param method    方法
     * @return          =true表示是，=false表示不是
     */
    public static boolean isStaticMethod(Method method)
    {
        return (method.getModifiers() & Modifier.STATIC) != 0;
    }
    
    /**
     * 判断是否是静态属性
     * 
     * @param field     属性
     * @return          =true表示是，=false表示不是
     */
    public static boolean isStaticField(Field field)
    {
        return (field.getModifiers() & Modifier.STATIC) != 0;
    }
    
    /**
     * 判断是否是临时属性
     * 
     * @param field     属性
     * @return          =true表示是，=false表示不是
     */
    public static boolean isTransientField(Field field)
    {
        return (field.getModifiers() & Modifier.TRANSIENT) != 0;
    }
    
    /**
     * 判断是否是静态属性或临时属性
     * 
     * @param field     属性
     * @return          =true表示是，=false表示不是
     */
    public static boolean isStaticTransientField(Field field)
    {
        return (field.getModifiers() & Modifier.STATIC) != 0 || (field.getModifiers() & Modifier.TRANSIENT) != 0;
    }
    
    /**
     * 获取类中指定的方法，该方法仅支持查询本类定义的属性
     * 
     * @param clazz     类结构
     * @param name      属性名称
     * @return          属性对应的结构 =null表示未查找，!=null表示查到
     */
    public static Method getMethod(Class<?> clazz, String name, Class<?>... parameterTypes)
    {
        try
        {
            return clazz.getDeclaredMethod(name, parameterTypes);
        }
        catch (Exception e) 
        {
            return null;
        }
    }
    
    /**
     * 获取类中指定的方法，支持深度查找，即如果没有则向上查询父类的属性
     * 
     * @param clazz 类结构
     * @param name 属性名称
     * @return 属性对应的结构 =null表示未查找，!=null表示查到
     */
    public static Method getMethodDeep(Class<?> clazz, String name, Class<?>... parameterTypes)
    {
        Method method = getMethod(clazz, name, parameterTypes);
        while (method == null)
        {
            if (clazz == Object.class || clazz.getSuperclass() == Object.class)
                break;
            
            clazz = clazz.getSuperclass();
            method = getMethod(clazz, name, parameterTypes);
        }
        
        return method;
    }
    
    /**
     * 获取类中指定的属性，该方法仅支持查询本类定义的属性
     * 
     * @param clazz 类结构
     * @param name 属性名称
     * @return 属性对应的结构 =null表示未查找，!=null表示查到
     */
    @AnNullable
    public static Field getField(Class<?> clazz, String name)
    {
        try
        {
            return clazz.getDeclaredField(name);
        }
        catch (Exception e) 
        {
            return null;
        }
    }
    
    /**
     * 获取类中指定的属性，支持深度查找，即如果没有则向上查询父类的属性
     * 
     * @param clazz 类结构
     * @param name 属性名称
     * @return 属性对应的结构 =null表示未查找，!=null表示查到
     */
    public static Field getFieldDeep(Class<?> clazz, String name)
    {
        return getFieldDeep(clazz, name, 0);
    }
    
    /**
     * 获取类中指定的静态属性，支持深度查找，即如果没有则向上查询父类的属性
     * 
     * @param cls       类结构
     * @param name      属性名称
     * @return          属性对应的结构 =null表示未查找，!=null表示查到
     */
    public static Field getFieldStaticDeep(Class<?> cls, String name)
    {
        return getFieldDeep(cls, name, 2);
    }
    
    /**
     * 获取类中指定的属性，支持深度查找，即如果没有则向上查询父类的属性
     * 
     * @param clazz     类结构
     * @param name      属性名称
     * @param type      查询类型，0表示所有的属性，1表示仅实例属性，静态和临时的除外，2表示仅静态属性
     * @return          属性对应的结构 =null表示未查找，!=null表示查到
     */
    public static Field getFieldDeep(Class<?> clazz, String name, int type)
    {
        Asserts.as((type >= 0 && type <= 2)?null:"查询属性类型，仅支持0,1,2请查看说明");
        
        while (true)
        {
            Field field = getField(clazz, name);
            if (field != null)
            {
                if (type == 0)
                    return field;
                else if (type == 1 && !isStaticTransientField(field))
                    return field;
                else if (type == 2 && isStaticField(field))
                    return field;
            }
            
            if (type != 1)
            {//不是仅查实例属性，时优先查接口
                Class<?>[] classes = clazz.getInterfaces();
                for (Class<?> cls : classes)
                {
                    field = getFieldDeep(cls, name, type);
                    if (field != null)
                        return field;
                }
            }
            
            if (clazz == Object.class)
                return null;
            
            //再找继承
            clazz = clazz.getSuperclass();
            if (clazz == null || clazz == Object.class)
                return null;//接口父接口为null,Object类无字段不需要再循环
        }
    }
    
    /**
     * 获取指定对象的字段值，异常抛unchecked异常
     * 
     * @param obj       对象
     * @param field     对象字段名称
     * @return          返回字段值
     */
    public static Object getFieldValue(Object obj, String field)
    {
        Asserts.notNull(field, "field");
        Field f = getField(obj.getClass(), field);

        return getFieldValue(obj, f);
    }
    
    /**
     * 获取指定对象的字段值，异常抛unchecked异常
     * 
     * @param obj       对象
     * @param field     对象字段
     * @return          返回字段值
     */
    public static Object getFieldValue(Object obj, Field field)
    {
        try
        {
            if (!field.isAccessible())
                field.setAccessible(true);
            return field.get(obj);
        }
        catch (Exception e)
        {
            throw Asserts.exception(e);
        }
    }
    
    /**
     * 设置指定对象的字段值，异常抛unchecked异常
     * 
     * @param obj       对象
     * @param field     对象字段
     * @param value     值
     */
    public static void setFieldValue(Object obj, Field field, Object value)
    {
        try
        {
            if (!field.isAccessible())
                field.setAccessible(true);
            field.set(obj, value);}
        catch (Exception e)
        {
            throw Asserts.exception(e);
        }
    }
    
    /**
     * 获取类中指定的字段列表，支持深度查找父类的字段列表(父类的循递归查找),静态和临时两种属性不拷贝
     * 
     * @param clazz 类
     * @return      返回字段列表，静态和临时除外
     */
    public static List<Field> getFieldListDeep(Class<?> clazz)
    {
        List<Field> fieldList = new ArrayList<>();
        getFieldListDeep(clazz, fieldList);
        return fieldList;
    }
    
    /**
     * 获取类中指定的属性列表，支持深度查找父类的字段列表(父类的循递归查找),静态和临时两种属性不拷贝
     * 
     * @param clazz     类
     * @param fieldList 用于存储的字段列表
     */
    public static void getFieldListDeep(Class<?> clazz, List<Field> fieldList)
    {
        Field[] fieldArr = clazz.getDeclaredFields();
        for (Field field : fieldArr)
        {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isTransient(mod) || "this$0".equals(field.getName()))
                continue;//静态和临时两种属性不拷贝，内部类指向外部类的引用不拷贝
            
            fieldList.add(field);
        }
        
        Class<?> superSrcClass = clazz.getSuperclass();
        if (superSrcClass != null && superSrcClass != Object.class)
        {
            getFieldListDeep(superSrcClass, fieldList);
        }
    }
    
    
    /**
     * 获取字段泛型，如类Abc中有一个字段list是List<String>的，则通过Abc.class和"list"获取String.class
     * 
     * @param cls       主类，如org.zhiqim.example.Abc.class
     * @param fieldName 字段名称，如"list"
     * @return
     */
    @AnNullable
    public static Class<?> getFieldGenericTypeOne(Field field)
    {
        ParameterizedType type = (ParameterizedType)field.getGenericType();
        if (type == null)
            return null;
        
        //读取第一个
        return (Class<?>)type.getActualTypeArguments()[0];
    }
    
    /**
     * 获取字段泛型，如类Abc中有一个字段list是List<String>的，则通过Abc.class和"list"获取String.class
     * 
     * @param cls       主类，如org.zhiqim.example.Abc.class
     * @param fieldName 字段名称，如"list"
     * @return
     */
    public static Class<?> getFieldGenericTypeOne(Class<?> cls, String fieldName)
    {
        Field field = getFieldDeep(cls, fieldName);
        Asserts.as(field != null?null:"类["+cls.getName()+"]字段["+fieldName+"]不存在或是静态临时字段");
        
        return getFieldGenericTypeOne(field);
    }
    
    /**
     * 判断方法是否最后一个参数是数组参数
     * 
     * @param method    方法
     * @return          =true表示是，=false表示不是
     */
    public static boolean isMethodLastParamArray(Method method)
    {
        Class<?>[] paramTypes = method.getParameterTypes();
        return paramTypes.length > 0 && Types.isArray(paramTypes[paramTypes.length-1]);
    }
    
    /**
     * 判断参数类型和和参数值是否匹配，要求个数相等，如果最后一个参数是数组的，请先组装好新的paramTypes
     * 
     * @param paramTypes 参数数组类型
     * @param paramArray 参数数组对象
     * @return           =true表示匹配成功
     */
    public static boolean isMethodParamMatch(Class<?>[] paramTypes, Object[] paramArray)
    {
        if (paramTypes.length != paramArray.length)
            return false;
        
        for (int i=0;i<paramTypes.length;i++)
        {
            Class<?> clazz = paramTypes[i];
            Object param = paramArray[i];
            if (param == null)
            {//参数为null时，要求不是基本类型
                if (Types.isPrimitive(clazz))
                    return false;
            }
            else if (Types.isPrimitive(clazz))
            {//基本类型，数值型不一定匹配，要适配
                if ((Types.isInteger(clazz) && !Types.isInteger(param))//long,int,short,byte
                    || (Types.isDecimal(clazz) && !Types.isDecimal(param))//float,double
                    || (Types.isBoolean(clazz) && !Types.isBoolean(param))//boolean
                    || (Types.isChar(clazz) && !Types.isChar(param)))//char
                {
                    return false;
                }
            }
            else if (i==paramTypes.length-1 && Types.isArray(clazz))
            {//最后一个数组支持实参不是数组，以便支持String... params的形参，而实参是"abc"的情况
                if (clazz != param.getClass() && !clazz.getComponentType().isAssignableFrom(param.getClass()))
                    return false;
            }
            else
            {//对象类型，判断是否其子类或本类
                if (clazz != param.getClass() && !clazz.isAssignableFrom(param.getClass()))
                    return false;
            }
        }
        
        return true;
    }
    
    /**
     * 反射调用指定类的静态无参数方法
     * 
     * @param cls           类
     * @param methodName    方法名
     * @return              调用结果
     * @throws Exception    异常
     */
    public static Object invoke(Class<?> cls, String methodName) throws Exception
    {
        return invoke(cls, methodName, null, null);
    }
    
    /**
     * 反射调用指定类的方法 
     * 
     * @param cls           类
     * @param methodName    方法名
     * @param obj           实例对象，为null只能访问静态对象
     * @param args          参数，为null表示无参数
     * @return              调用结果
     * @throws Exception    异常
     */
    public static Object invoke(Class<?> cls, String methodName, Object obj, Object[] args) throws Exception
    {
        Asserts.as(cls != null?null:"类参数不能为null");
        Asserts.as(Validates.isNotEmptyBlank(methodName)?null:"方法名不能为空");
        
        if (args == null)
        {//无参数
            args = new Object[0];
        }
        
        Method[] methods = cls.getMethods();
        for (Method method : methods)
        {
            if (!methodName.equals(method.getName()))
                continue;
            
            if (obj == null && !isStaticMethod(method))
                continue;
            
            if (!Classes.isMethodParamMatch(method.getParameterTypes(), args))
                continue;

            return method.invoke(obj, args);
        }
        
        throw Asserts.exception("类["+cls.getName()+"]不存在["+methodName+"]或参数不一致或非静态方法未传对象");
    }
}
